/**
 * 语音识别模块类，负责处理语音识别的相关操作。
 *
 * @author linxiongjun
 * @date 2025-05-29
 */
package com.asr.plugin_asr

import com.asr.plugin_asr.ktx.log
import com.asr.plugin_asr.params.ASRParams
import com.iflytek.sparkchain.core.asr.ASR
import com.iflytek.sparkchain.core.asr.AsrCallbacks

/**
 * 语音识别类，封装了讯飞语音识别的初始化、启动和停止监听功能。
 */
class SpeechRecognition {
    // 讯飞ASR实例
    private var asr: ASR? = null
    // 是否正在运行语音识别监听
    private var isAsrListenerRun = false
    // 语音识别结果回调函数
    private var asrListenerResultCallback: ((String) -> Unit)? = null
    private var asrListenerProcessCallback: ((String) -> Unit)? = null
    // 语音识别参数配置
    private val aSRParams = ASRParams()

    /**
     * 初始化讯飞ASR实例，并设置回调函数。
     */
    private fun initASR() {
        if (asr == null) {
            asr = ASR()
            asr!!.registerCallbacks(object: AsrCallbacks {
                /**
                 * 识别结果回调
                 *
                 * @param asrResult 识别结果对象
                 * @param p1 额外参数（通常为null）
                 */
                override fun onResult(asrResult: ASR.ASRResult, p1: Any?) {
                    val begin = asrResult.begin         // 识别结果所处音频的起始点
                    val end = asrResult.end           // 识别结果所处音频的结束点
                    val status = asrResult.status        // 结果数据状态，0：识别的第一块结果,1：识别中间结果,2：识别最后一块结果
                    val result = asrResult.bestMatchText // 识别结果
                    val sid = asrResult.sid           // sid
                    val vads = asrResult.vads
                    val transcriptions = asrResult.transcriptions
                    var vad_begin = -1
                    var vad_end = -1
                    var word: String? = null
                    for (vad in vads) {
                        vad_begin = vad.getBegin()
                        vad_end = vad.getEnd()
                        "vad={begin:$vad_begin,end:$vad_end}".log()
                    }
                    for (transcription in transcriptions) {
                        val segments = transcription.getSegments()
                        for (segment in segments) {
                            word = segment.getText()              // 分词结果
                            ("word={word:$word}").log()
                        }
                    }
                    ("result={begin:$begin,end:$end,status:$status,result:$result,sid:$sid}").log()
                    if (asrListenerProcessCallback != null) {
                        asrListenerProcessCallback!!(result)
                    }
                    if (status == 2) {
                        if(asrListenerResultCallback != null) {
                            asrListenerResultCallback!!(result)
                        }
                        stopAsrListener()
                    }
                }
                /**
                 * 错误回调
                 *
                 * @param asrError 错误对象
                 * @param p1 额外参数（通常为null）
                 */
                override fun onError(asrError: ASR.ASRError, p1: Any?) {
                    val code = asrError.code
                    val msg = asrError.errMsg
                    val sid = asrError.sid
                    val info = "error={code:$code,msg:$msg,sid:$sid}"
                    (info).log()
                    stopAsrListener()
                }

                /**
                 * 开始说话回调
                 */
                override fun onBeginOfSpeech() {
                    // 可在此处添加开始说话时的逻辑
                }

                /**
                 * 结束说话回调
                 */
                override fun onEndOfSpeech() {
                    // 说话结束时停止监听
                    stopAsrListener()
                }
            })
        }
    }

    /**
     * 停止语音识别监听。
     */
    fun stopAsrListener() {
        asr?.stopListener(false)
        isAsrListenerRun = false
    }

    /**
     * 启动语音识别监听，并设置结果回调函数。
     *
     * @param asrListenerResultCallback 语音识别结果的回调函数
     * @return 启动结果，0表示成功，非0表示失败
     */
    fun startAsrListener(language: String, asrListenerResultCallback: (result: String) -> Unit, asrListenerProcessCallback: (result: String) -> Unit): Int {
        this.asrListenerResultCallback = asrListenerResultCallback
        this.asrListenerProcessCallback = asrListenerProcessCallback
        if (isAsrListenerRun) {
            return -1
        }
        initASR()
        asr!!.apply {
            language(language) //语种，zh_cn:中文，en_us:英文。其他语种参见集成文档
            domain(aSRParams.domain) //应用领域,iat:日常用语。其他领域参见集成文档
            accent(aSRParams.accent) //方言，mandarin:普通话。方言仅当language为中文时才会生效。其他方言参见集成文档。
            vinfo(aSRParams.vinfo) //返回子句结果对应的起始和结束的端点帧偏移值。
            dwa(aSRParams.dwa) //动态修正
        }

        val ret: Int = asr!!.startListener("asr")
        if (ret == 0) {
            isAsrListenerRun = true
        }
        return ret
    }

}